#pragma once

#include "Platform.h"
#include "../EntityManager.h"
#include "../Market/Comodities.h"

/*
	This class may also be a good candidate to replace the comodity market class.
	Since it keeps track of all the sales data it would be convienent to resolve all
	the orders here.

	I could handle the resource bidding iteratively, gather up all the buys and sells for only 1 resource
	then resolve just those, then loop through the rest of the resources. This might provide some threading opportunities.
*/

class ComodityManager
{
private:
	// An instance of Production Data.
	struct InstanceData
	{
		uint32 size;
		uint32 capacity;
		void* buffer;

		//Entity* entity;				// The entity owning this instance. (resource)
		uint32* comodity_hash;
		uint32* registered_buyers;	// the number registered for each resource.
		uint32* registered_sellers;

		PriceTracking* previuos_turns;
		float* mean;

		float* supply;
		float* demand;

	};

private:
	InstanceData _data;

	void Allocate(const uint32 capacity);

public:
	ComodityManager();
	~ComodityManager();

	void Initialize(const OpenVector<uint32>& comodities);
	void InitializeBuyData(BidData* bid_data) const;
	void InitializeSellData(BidData* bid_data) const;

	void SortBuyData(BidData& buy_data, uint32 left, uint32 right) const;
	void SortSellData(BidData& sell_data, uint32 left, uint32 right) const;

	void ReCalculateSupply(const BidData* const sell_data);
	void ReCalculateDemand(const BidData* const buy_data);
	void ResolveSales(BidData* buy_data, BidData* sell_data);

	const uint32 DetermineFactoryType(); // returns the hash.
	void RegisterBuyers(const OpenMap<uint32, uint32>& register_buyers);
	void RegisterSellers(const OpenMap<uint32, uint32>& register_sellers);
	void DeregisterBuyers(const OpenMap<uint32, uint32>& defunct_buyers);
	void DeregisterSellers(const OpenMap<uint32, uint32>& defunct_sellers);

	inline const uint32 GetNumResources() { return _data.size; }
	inline const float* const GetComodityMeans() { return _data.mean; }
	inline const float* const GetComoditySupply() { return _data.supply; }
	inline const float* const GetComodityDemand() { return _data.demand; }
};